﻿using System;
using System.Data;
using System.Text;
using System.Collections.Generic;


namespace WinFormClient
{
    public abstract class DataObject
    {
        private string _tableName;
        protected string _className;
        protected string _nameSpace;
        protected ColumnMapCollection _col;
        protected bool _isBuildModel = false;
        private int _lenghtForIgnoreParameter = 5000;

        public DataObject(string tableName, string className, string nameSpace, int lengthForIgnoreParameter, bool addAttributes, ColumnMapCollection col)
        {
            this._tableName = tableName;
            this._col = col;
            this._lenghtForIgnoreParameter = lengthForIgnoreParameter;
            this._className = className;
            this._isBuildModel = addAttributes;
            this._nameSpace = nameSpace;
        }

        public DataObject(string tableName, string className, string nameSpace, bool addAttributes, ColumnMapCollection col)
        {
            this._tableName = tableName;
            this._col = col;
            this._className = className;
            this._isBuildModel = addAttributes;
            this._nameSpace = nameSpace;
        }

        public abstract void Builder();

        public void Dispose()
        {
            this._col.Dispose();
        }

        #region header
        protected string Header(string inherit)
        {
            StringBuilder sb = new StringBuilder(this.Namespance);
            sb.Append("    public partial class " + this._className + (!String.IsNullOrEmpty(inherit) ? (":"+inherit) : "") + Environment.NewLine);
            sb.Append("    {" + Environment.NewLine);
            if (_isBuildModel)
            {
                int s = 0;
                for (int i = 0; i < this._col.Count; i++)
                {
                    if (_col[i].CsDataType == "string") s++;
                }
                sb.Append("        IList<string> _propertyLengthsOverflow = new List<String>(" + s + ");" + Environment.NewLine);
            }
            return sb.ToString();
        }

        protected string ParameterHeader()
        {
            StringBuilder sb = new StringBuilder(this.Namespance);
            sb.Append("    public partial class " + this._className + ":Model."+this._tableName+ Environment.NewLine);
            sb.Append("    {" + Environment.NewLine);
            return sb.ToString();
        }

        private string Namespance
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("#region namespace" + Environment.NewLine);
                sb.Append("using System;" + Environment.NewLine);
                sb.Append("using System.Collections.Generic;" + Environment.NewLine);
                sb.Append("using System.Text;" + Environment.NewLine);
                sb.Append("using WAF.COM.Core;" + Environment.NewLine);
                sb.Append("#endregion" + Environment.NewLine);
                sb.Append(Environment.NewLine);
                sb.Append("namespace " + MapXml.NameSpace + "." + this._nameSpace + Environment.NewLine);
                sb.Append("{" + Environment.NewLine);

                return sb.ToString();
            }
        }

        #endregion

        #region fields
        protected string Fields()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("        #region fields" + Environment.NewLine);
            for (int i = 0; i < this._col.Count; i++)
            {
                if (this._col[i].DataLength > this._lenghtForIgnoreParameter) continue;

                sb.Append("        private " + this._col[i].CsDataType + " " + this._col[i].FieldName + (String.IsNullOrEmpty(this._col[i].Defaultvalue)?"":("=" + this._col[i].Defaultvalue)) + ";" + Environment.NewLine);
            }
            sb.Append("        #endregion" + Environment.NewLine);
            sb.Append(Environment.NewLine);

            return sb.ToString();
        }
        #endregion

        #region Const
        protected string Const()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("        #region const" + Environment.NewLine);
            for (int i = 0; i < this._col.Count; i++)
            {
                if (this._col[i].DataLength > this._lenghtForIgnoreParameter) continue;
                sb.Append("        public const string " + this._col[i].PropertyName.ToUpper() + " = \"" + this._col[i].ColumnName + "\";" + Environment.NewLine);
            }
            sb.Append("        #endregion" + Environment.NewLine);
            sb.Append(Environment.NewLine);

            return sb.ToString();
        }
        #endregion

        #region structure
        protected string Structure()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("        #region structure" + Environment.NewLine);

            sb.Append("        public " + this._className + "()" + Environment.NewLine);
            sb.Append("        {}" + Environment.NewLine);
            sb.Append(Environment.NewLine);

            string param = "";
            for (int i = 0; i < this._col.Count; i++)
            {
                if (this._col[i].DataLength > this._lenghtForIgnoreParameter) continue;
                if (param != "") param += ",";
                param += this._col[i].CsDataType + " " + Tools.FieldConvert(this._col[i].PropertyName).Replace("_", "");
            }

            if (param != "")
            {
                sb.Append("        public " + this._className + "(" + param + ")" + Environment.NewLine);
                sb.Append("        {" + Environment.NewLine);

                for (int i = 0; i < this._col.Count; i++)
                {
                    if (this._col[i].DataLength > this._lenghtForIgnoreParameter) continue;

                    sb.Append("            this." + Tools.FieldConvert(this._col[i].PropertyName) + " = " + Tools.FieldConvert(this._col[i].PropertyName).Replace("_", "") + ";" + Environment.NewLine);
                }
                sb.Append("        }" + Environment.NewLine);
            }

            sb.Append("        #endregion" + Environment.NewLine);
            sb.Append(Environment.NewLine);

            return sb.ToString();

        }
        #endregion

        #region property
        protected string Property()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("        #region property" + Environment.NewLine);
            for (int i = 0; i < this._col.Count; i++)
            {
                if (this._col[i].DataLength > this._lenghtForIgnoreParameter) continue;
                sb.Append(Environment.NewLine);
                if (!String.IsNullOrEmpty(this._col[i].Comments))
                {
                    sb.Append("        /// <summary>" + Environment.NewLine);
                    sb.Append("        /// " + this._col[i].Comments + Environment.NewLine);
                    sb.Append("        /// </summary>" + Environment.NewLine);
                }

                if (this._col[i] == this._col.PrimaryKeyColumn) sb.Append("        [KeyField]" + "" + Environment.NewLine);
                if (this._col[i].Visibility == "0" && this._col[i].Editable == "0")
                { }
                else
                {
                    sb.AppendLine("        [BoundField(" +
                        this._col[i].VisibleIndex +
                        this._col[i].DevGridControl.GetName<DevGridControlType>() +
                        this._col[i].Visibility.GetName<Visibilities>() +
                        this._col[i].Editable.GetName<Editable>() +
                        ",\"" + this._col[i].Spin + "\"" +
                        ((this._isBuildModel && _col[i].CsDataType == "string")?("," + _col[i].DataLength):"") + ")]");
                }

                if (this._col[i].NotNull) sb.AppendLine("        [NotNullField]");

                sb.Append("        public " + this._col[i].CsDataType + " " + this._col[i].PropertyName + "" + Environment.NewLine);
                sb.Append("        {" + Environment.NewLine);
                sb.Append("            get { return this." + Tools.FieldConvert(this._col[i].PropertyName) + "; }" + Environment.NewLine);
                sb.Append("            set { " + Environment.NewLine);
                if (this._isBuildModel && _col[i].CsDataType == "string" && !_col[i].DbDataType.StartsWith("LONG"))
                {
                    sb.Append("                if(value.ByteLength() > " + _col[i].DataLength + ") _propertyLengthsOverflow.Add(\"" + Tools.PropertyConvert(this._col[i].PropertyName) + "\"); " + Environment.NewLine);
                }
                sb.Append("                this." + Tools.FieldConvert(this._col[i].PropertyName) + " = value; " + Environment.NewLine);
                sb.Append("             }" + Environment.NewLine);
                sb.Append("        }" + Environment.NewLine);

            }

            if (this._isBuildModel)
            {
                sb.Append(Environment.NewLine);
                sb.Append("        /// <summary>" + Environment.NewLine);
                sb.Append("        /// String Properties Length overflow." + Environment.NewLine);
                sb.Append("        /// </summary>" + Environment.NewLine);
                sb.Append("        public IList<string> PropertyLengthsOverflow" + Environment.NewLine);
                sb.Append("        {" + Environment.NewLine);
                sb.Append("            get { return this._propertyLengthsOverflow; }" + Environment.NewLine);
                sb.Append("        }" + Environment.NewLine);
            }

            sb.Append("        #endregion" + Environment.NewLine);
            sb.Append(Environment.NewLine);

            return sb.ToString();
        }
        #endregion

        #region Properties Name
        protected string PropertyNames()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("        #region Properties" + Environment.NewLine);
            for (int i = 0; i < this._col.Count; i++)
            {
                if (this._col[i].DataLength > this._lenghtForIgnoreParameter) continue;
                sb.Append("        public const string " + this._col[i].ColumnName + " = \"" + this._col[i].PropertyName + "\";" + Environment.NewLine);
            }
            sb.Append("        #endregion" + Environment.NewLine);
            sb.Append(Environment.NewLine);

            return sb.ToString();
        }
        #endregion

        #region unlimitedQuery
        protected string UnlimitedQuery()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("        #region unlimitedQuery" + Environment.NewLine);
            sb.Append("        /// <summary>" + Environment.NewLine);
            sb.Append("        /// unlimited for where condition. please use the instance's const fields to org the condition." + Environment.NewLine);
            sb.Append("        /// </summary>" + Environment.NewLine);
            sb.Append("        private string _unlimitedQuery;" + Environment.NewLine);
            sb.Append("        public string UnlimitedQuery" + Environment.NewLine);
            sb.Append("        {" + Environment.NewLine);
            sb.Append("            get { return this._unlimitedQuery; }" + Environment.NewLine);
            sb.Append("            set { this._unlimitedQuery = value; }" + Environment.NewLine);
            sb.Append("        }" + Environment.NewLine);

            sb.Append("        #endregion" + Environment.NewLine);

            return sb.ToString();
        }
        #endregion

        #region footer
        protected string Footer()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("    }" + Environment.NewLine);
            sb.Append("}" + Environment.NewLine);
            return sb.ToString();
        }
        #endregion
    }
}
